<?php

namespace App\Http\Controllers\User;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Validator;
use DB;
use App\Http\Controllers\BaseController;
use App\Models\User;
use App\Http\Lib\Util;
use App\Http\Lib\UserLib;
use App\Http\Lib\HttpClient;
use App\Entity\UserEntity;
use Carbon\Carbon;
use Log;
use Cache;

class TokenAuthController extends BaseController
{
    public function login (Request $request) {
        $field = self::userName();
        $validator = Validator::make($request->all(), [
             $field  => 'required',
            'password' => 'required|between:5,12',
        ]);
        if($validator->fails()) return $this->respondWithFailedValidation($validator);
    
        
        $user = User::where($field, $request->$field)->first();
    
        if($user) {
            if(password_verify($request->password, $user->password)) {
                $user->api_token = $this->generateApiToken();
                $user->save();
                return $this->respondWithToken($user->api_token);
            }else {
                return $this->respondWithErrors('密码错误');
            }
    
        } else {
            return $this->respondWithErrors('用户找不到');
        }
    }
    
    public function register(Request $request) {
        $field = self::userName();
        $validator = Validator::make($request->all(), [
            $field   => 'required|unique:users',
            'password' => 'required',
        ]);
        if($validator->fails()) return $this->respondWithFailedValidation($validator);
    
        $user = new User([
            $field => $request->$field,
            'password' => bcrypt($request->password),
        ]);
        $user->api_token = $this->generateApiToken();
        $check = $user->save();
        if($check) {
            return $this->respondWithToken($user->api_token);
        } else {
            return $this->respondWithErrors('注册失败');
        }
    }
    
    static protected function userName() {
        return 'name';
    }
    
    static public function generateApiToken() {
        return uniqid(base64_encode(str_random(60)));
    }
    
    public function getUcLoginUrl($site_id = 0) {
        //$site_id = $request->input('site_id', 0);       # 登录后选择的站点id
        $url = Util::genUrl(env('USERCENTER_LOGIN_URL'));
        return $url;
    }
    
    public function ucLoginUrl(Request $request) {
//         $site_id = $request->input('site_id', 0);       # 登录后选择的站点id
        $url = $this->getUcLoginUrl();
        return $this->respondWithSuccess('ok', $url);
    }
    
    protected function respondWithToken($token)
    {
        return response()->json([
            'errcode' => 0,
            'errmessage'  => 'ok',
            'access_token' => $token,
            'token_type' => 'bearer',
        ]);
    }
    
    // 从用户中心登录,授权登陆回调
    public function logined(Request $request){
        $validator = Validator::make(request()->all(), [
            'access_token' => 'required',
        ]);
        if($validator->fails()) return $this->respondWithFailedValidation($validator);
        // dd($request->all());
        $r = $this->privateApi('POST', env('USERCENTER_URL') . '/api/oauth/info', 
                               ['access_token' => $request->access_token]);
        if(empty($r))
            return $this->respondWithErrors('获取用户信息失败(1)');
    
        $arr = json_decode($r, true);
    
        //var_dump($r, $arr);
        if(!isset($arr['errcode']))
            return $this->respondWithErrors('获取用户信息失败(2)');
        if($arr['errcode'] != 0)
            return $this->respondWithErrors('获取用户信息失败(3)');
         
        $data = $arr['data'];
        $user = $data['user'];
        // dd($data);
        $localuser = User::where('uc_userid', $user['_id'])->first();
        if(!$localuser) {
            $localuser = new User();
            $localuser->uc_userid = $user['_id'];
        }
        $localuser->name = $user['name'];
        $localuser->email = $user['email'];
        $localuser->ban = 0;
        $localuser->deleted_at = null;
        $localuser->latest_access = Carbon::now();
        $localuser->api_token = $this->generateApiToken();
    
        $login = $localuser->save();
        if($login) {
            $logout_token = $data['logout_token'];
            Cache::put(sprintf('logout_token@%s', $logout_token), $localuser->_id, 60*24*7);
            Cache::put('logout_token:'.$localuser->_id, $logout_token, 60*24*30);
            Cache::forever('userinfo:'.$localuser->_id, $r);
            $api_token = $localuser->api_token;
            return $this->respondWithToken($api_token);
        } else
            return $this->respondWithErrors('登录失败');
    }
    
    //用户中心调用登出
    public function uclogout(Request $request){
        $logout_token = $request->logout_token;
    
        $ip = $request->ip();
        if(!in_array($ip, explode('|', env('USERCENTER_IPS'))))
            return ['errcode' => 1, 'errmessage' => sprintf('ip不允许访问:%s', $ip)];
        $user_id = Cache::get(sprintf('logout_token@%s', $logout_token));
        if(!$user_id)
            return ['errcode' => 1, 'errmessage' => 'logout_token已失效'];
        
        $user = User::find($user_id);
        if($user) {
            $check = $user->update(['api_token' => null]);
            return ['errcode' => 0, 'errmessage' => 'ok'];
        } else {
            return ['errcode' => 1, 'errmessage' => '用户找不到'];
        }
    }
    
    // 本地登出
    public function logout(Request $request, UserEntity $userEntity) {
        $user = $userEntity->getModel();
        
        if($user) {
            $check = $user->update(['api_token' => null]);
            $key = 'logout_token:'.$user->_id;
            $logout_token = Cache::get($key);
            if(!$logout_token)  {
                Log::error(__METHOD__, ['error' => 'logout_token缓存已失效']);
            } else {           
                $r = $this->privateApi('POST', env('USERCENTER_URL') . '/usercenter/logout', 
                            ['logout_token' => $logout_token]);
                $data = json_decode($r, true);
                if(!key_exists('errcode', $data)) {
                    Log::info(__METHOD__, ['error' => $r]);
                }
                if($data['errcode'] !== 0){
                    Log::info(__METHOD__, $data);
                }
            }
            Cache::forget($key);
            return $this->respondWithSuccess('用户登出');
        } else {
            return $this->respondWithErrors('用户找不到');
        }
    }
    
}
